package com.ruge.test.基础.数组;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;

/**
 * 爱丽丝、如歌  创建于 2018/8/27 19:55
 * 说明:  一维数组基础及常见算法
 */
public class 一维数组 {
	/**
	 * 数组的声明
	 */
	@Test
	public void declare() {
		int[] a;
		String[] b;
		Boolean[] c;
		float[] d;
	}

	/**
	 * 数组动态初始化
	 */
	@Test
	public void initByDynamic() {
		int[] arr = new int[2];
		arr[0] = 1;
		arr[1] = 1;
	}

	/**
	 * 数组静态初始化
	 */
	@Test
	public void initByStatic() {
		int[] arr = {1, 2, 3, 4, 5};
	}

	/**
	 * 数组的长度
	 */
	@Test
	public void getLength() {
		int[] arr = {1, 2, 3, 4, 5};
		System.out.println(arr.length);
	}
	/**
	 * 数组的遍历
	 */
	@Test
	public void ergodic() {
		int[] arr = {1, 2, 3, 4, 1, 2, 4, 3};
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
	}

	/**
	 * 通过for循环方式进行复制
	 * 代码灵活，但效率低。
	 */
	@Test
	public void copyOne(){
		int [] arr1 = {1,2,3,4,5};
		int [] arr2 = new int[arr1.length];
		for (int i = 0; i <arr1.length ; i++) {
			arr2[i] = arr1[i];
		}
		for (int i = 0; i <arr2.length ; i++) {
			System.out.print(arr2[i]+" ");
		}
	}

	/**
	 * 通过 System.arraycopy()方法进行复制
	 * 　　通过源码可以看到，其为native方法，即原生态方法。自然效率更高。
	 */
	@Test
	public void copyTwo(){
		int [] arr1 = {1,2,3,4,5};
		int [] arr2 = new int[arr1.length];
		/**
		 * （原数组， 原数组的开始位置， 目标数组， 目标数组的开始位置， 拷贝个数）
		 */
		System.arraycopy(arr1,0,arr2,0,arr1.length);
		for (int i = 0; i <arr2.length ; i++) {
			System.out.print(arr2[i]+" ");
		}
	}

	/**
	 *通过for循环实现数组反转
	 */
	@Test
	public void reverseOne(){
		int [] arr1 = {1,2,3,4,5};
		int [] arr2 = new int[arr1.length];
		for (int i = 0; i <arr1.length ; i++) {
			arr2[arr1.length-i-1] = arr1[i];
		}
		for (int i = 0; i <arr2.length ; i++) {
			System.out.print(arr2[i]+" ");
		}
	}

	/**
	 * 数组反转
	 */
	@Test
	public void reverseTwo(){
		ArrayList<String> arrayList = new ArrayList<String>();
		arrayList.add("A");
		arrayList.add("B");
		arrayList.add("C");
		arrayList.add("D");
		arrayList.add("E");
		System.out.println("反转前排序: " + arrayList);
		Collections.reverse(arrayList);
		System.out.println("反转后排序: " + arrayList);
	}

	/**
	 * 数组的排序
	 * 		插入排序
	 * 			直接插入排序
	 * 			折半插入排序
	 * 			Shell排序
	 * 		交换排序
	 * 			冒泡排序
	 * 			快速排序
	 * 		选择排序
	 * 			简单选择排序
	 * 			堆排序
	 * 		归并排序
	 * 		基数排序
	 *
	 */
	/**
	 * 冒泡排序
	 * 原理：比较两个相邻的元素，将值大的元素交换至右端。
	 * 思路：依次比较相邻的两个数，将小数放在前面，大数放在后面。即在第一趟：首先比较第1个和第2个数，将小数放前，大数放后。然后比较第2个数和第3
	 * 		 个数，将小数放前，大数放后，如此继续，直至比较最后两个数，将小数放前，大数放后。重复第一趟步骤，直至全部排序完成。
	 *       第一趟比较完成后，最后一个数一定是数组中最大的一个数，所以第二趟比较的时候最后一个数不参与比较；
	 *       第二趟比较完成后，倒数第二个数也一定是数组中第二大的数，所以第三趟比较的时候最后两个数不参与比较；
	 *       依次类推，每一趟比较次数-1；
	 */
	@Test
	public void sortOne(){
		int[] arr =new int  [10];
		arr[0] = (int) (1 + Math.random() * (10 - 1 + 1));
		arr[1] = (int) (1 + Math.random() * (10 - 1 + 1));
		arr[2] = (int) (1 + Math.random() * (10 - 1 + 1));
		arr[3] = (int) (1 + Math.random() * (10 - 1 + 1));
		arr[4] = (int) (1 + Math.random() * (10 - 1 + 1));
		arr[5] = (int) (1 + Math.random() * (10 - 1 + 1));
		arr[6] = (int) (1 + Math.random() * (10 - 1 + 1));
		arr[7] = (int) (1 + Math.random() * (10 - 1 + 1));
		arr[8] = (int) (1 + Math.random() * (10 - 1 + 1));
		arr[9] = (int) (1 + Math.random() * (10 - 1 + 1));
		System.out.print("排序前");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(+arr[i]+" ");
		}

		for(int i=0;i<arr.length-1;i++){//外层循环控制排序趟数
			System.out.println();
			System.out.print("排序后第"+i+"次数的结果");
			for (int ii = 0; ii < arr.length; ii++) {
				System.out.print(+arr[ii]+" ");
			}

			for(int j=0;j<arr.length-1-i;j++){//内层循环控制每一趟排序多少次
				 if(arr[j]>arr[j+1]){
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                 }
            }
        }
		System.out.println();
		System.out.print("排序后");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(+arr[i]+" ");
		}
		
	}
}
